center box: Support expand property
authorMatthias Clasen <mclasen@redhat.com>
Sun, 4 Jun 2017 02:44:19 +0000 (22:44 -0400)
committerMatthias Clasen <mclasen@redhat.com>
Mon, 5 Jun 2017 01:21:00 +0000 (21:21 -0400)
We expand the center child first, but only as far
as we can keep it centered.

gtk/gtkcenterbox.c

index 1a19fa1b87c79ce0c1edbb1c482d5c0056310be3..45599f5893f19fc67c4649006798437e1cfe1415 100644 (file)
@@ -46,6 +46,8 @@
 #include "gtkcenterbox.h"
 #include "gtkcssnodeprivate.h"
 #include "gtkwidgetprivate.h"
+#include "gtkorientable.h"
+#include "gtkorientableprivate.h"
 #include "gtkbuildable.h"
 
 struct _GtkCenterBox
@@ -163,6 +165,9 @@ gtk_center_box_size_allocate (GtkWidget     *widget,
   int right_min = 0;
   int right_nat = 0;
   int avail;
+  gboolean left_expand = FALSE;
+  gboolean center_expand = FALSE;
+  gboolean right_expand = FALSE;
 
   if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
     {
@@ -192,35 +197,29 @@ gtk_center_box_size_allocate (GtkWidget     *widget,
                         allocation->height,
                         &center_min, &center_nat, NULL, NULL);
 
-  child_allocation.y = allocation->y;
-  child_allocation.height = allocation->height;
-
-  center_size = CLAMP (allocation->width - (left_min + right_min), center_min, center_nat);
+  if (self->center_widget)
+    {
+      center_size = CLAMP (allocation->width - (left_min + right_min), center_min, center_nat);
+      center_expand = gtk_widget_get_hexpand (self->center_widget);
+    }
 
   if (left)
     {
       avail = MIN ((allocation->width - center_size) / 2, allocation->width - (center_size + right_min));
-      child_allocation.width = CLAMP (avail, left_min, left_nat);
-      child_allocation.x = allocation->x;
-
-      gtk_widget_size_allocate (left, &child_allocation);
-      gtk_widget_get_clip (left, &child_clip);
-      gdk_rectangle_union (&clip, &clip, &child_clip);
-      left_size = child_allocation.width;
+      left_size = CLAMP (avail, left_min, left_nat);
+      left_expand = gtk_widget_get_hexpand (left);
     }
 
   if (right)
     {
       avail = MIN ((allocation->width - center_size) / 2, allocation->width - (center_size + left_min));
-      child_allocation.width = CLAMP (avail, right_min, right_nat);
-      child_allocation.x = allocation->x + allocation->width - child_allocation.width;
-
-      gtk_widget_size_allocate (right, &child_allocation);
-      gtk_widget_get_clip (right, &child_clip);
-      gdk_rectangle_union (&clip, &clip, &child_clip);
-      right_size = child_allocation.width;
+      right_size = CLAMP (avail, right_min, right_nat);
+      right_expand = gtk_widget_get_hexpand (right);
     }
 
+  child_allocation.y = allocation->y;
+  child_allocation.height = allocation->height;
+
   if (self->center_widget)
     {
       child_allocation.width = center_size;
@@ -231,11 +230,57 @@ gtk_center_box_size_allocate (GtkWidget     *widget,
         child_allocation.x = left_size;
       else if (allocation->width - right_size < child_allocation.x + child_allocation.width)
         child_allocation.x = allocation->width - child_allocation.width - right_size;
+      else if (center_expand)
+        {
+          child_allocation.width = allocation->width - 2 * MAX (left_size, right_size);
+          child_allocation.x = (allocation->width / 2) - (child_allocation.width / 2);
+        }
 
       child_allocation.x += allocation->x;
       gtk_widget_size_allocate (self->center_widget, &child_allocation);
       gtk_widget_get_clip (self->center_widget, &child_clip);
       gdk_rectangle_union (&clip, &clip, &child_clip);
+
+      if (left_expand)
+        left_size = child_allocation.x - allocation->x;
+
+      if (right_expand)
+        right_size = allocation->x + allocation->width - (child_allocation.x + child_allocation.width);
+    }
+  else
+    {
+      avail = allocation->width - (left_size + right_size);
+      if (left_expand && right_expand)
+        {
+          left_size += avail / 2;
+          right_size += avail / 2;
+        }
+      else if (left_expand)
+        {
+          left_size += avail;
+        }
+      else if (right_expand)
+        {
+          right_size += avail;
+        }
+    }
+
+  if (left)
+    {
+      child_allocation.width = left_size;
+      child_allocation.x = allocation->x;
+      gtk_widget_size_allocate (left, &child_allocation);
+      gtk_widget_get_clip (left, &child_clip);
+      gdk_rectangle_union (&clip, &clip, &child_clip);
+    }
+
+  if (right)
+    {
+      child_allocation.width = right_size;
+      child_allocation.x = allocation->x + allocation->width - child_allocation.width;
+      gtk_widget_size_allocate (right, &child_allocation);
+      gtk_widget_get_clip (right, &child_clip);
+      gdk_rectangle_union (&clip, &clip, &child_clip);
     }
 
   gtk_widget_set_clip (widget, &clip);